type PromiseFile = (value: File) => void;
type PromiseBase64 = (value: string) => void;
type PromiseBlob = (value: Blob) => void;

/**
 * 文件互转
 * @author Sheeppp
 * @param url 图片网络地址
 * @returns Promise(file)
 */
export function urlToFile(url: string) {
    return new Promise((resolve: PromiseFile) => {
        fetch(url).then(data => data.blob()).then(blob => {
            let file = new File([blob], `${Date.now()}.${blob.type.split('/')[1]}`, { type: blob.type, lastModified: Date.now() });
            resolve(file);
        });
    });
}
/**
 * 
 * @param blob 图片的blob对象
 * @returns Promise(file)
 */
export function blobToFile(blob: Blob) {
    return new Promise((resolve: PromiseFile) => {
        let file = new File([blob], `${Date.now()}.${blob.type.split('/')[1]}`, { type: blob.type, lastModified: Date.now() });
        resolve(file);
    }); 
}
/**
 * 
 * @param dataurl 图片的base64
 * @param filename 图片名称，默认：file
 * @returns Promise(file)
 */
export async function base64ToFile(dataurl: string, filename = "file") {
  let arr = dataurl.split(",");
  let arr0 = arr[0] ? arr[0] : '';
  let mime = arr0.match(/:(.*?);/)![1] || '';
  let suffix = mime.split("/")[1];
  let bstr = atob(arr[1]);
  let n = bstr.length;
  let u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new File([u8arr], `${filename}.${suffix}`, {
    type: mime
  });
};
/**
 * 
 * @param base64 图片的base64
 * @returns Promise(blob)
 */
export function base64ToBlob(base64: string) {
    var arr = base64.split(','),
        mime = arr.length > 0 ? arr[0].split(',')[1] : '',
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n);
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new Promise((resolve: PromiseBlob) => {
        resolve(new Blob([u8arr], { type: mime }))
    });
}
/**
 * 
 * @param url 图片的网络地址
 * @returns Promise(blob)
 */
export function urlToBlob(url: string) {
    return new Promise((resolve: PromiseBlob) => {
        fetch(url).then(data => data.blob()).then(blob => {
            resolve(blob);
        });
    });
}
/**
 * 
 * @param file 图片文件
 * @returns Promise(blob)
 */
export function fileToBlob(file: File) {
    return new Promise((reslove: PromiseBlob) => {
        const reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = (e) => reslove(new Blob([e.target!.result!], { type: file.type }));
    })
}
/**
 * 
 * @param url 图片网络地址
 * @returns Promise(base64)
 */
export function urlToBase64(url: string) {
    return new Promise((resolve: PromiseBase64) => {
        let img = new Image;
        let canvas = document.createElement('canvas');
        let ctx = canvas.getContext('2d')!;
        img.crossOrigin = 'anonymous';//也需要后端的支持
        img.onload = function () {
            canvas.width = img.width;
            canvas.height = img.height;
            ctx.drawImage(img, 0, 0);
            resolve(canvas.toDataURL());
        }
        img.src = url;
    });
}
/**
 * 
 * @param file blob对象
 * @returns Promise(base64)
 */
export const blobToBase64 = fileToBase64;
/**
 * 
 * @param file file对象
 * @returns Promise(base64)
 */
export function fileToBase64(file: File) {
    return new Promise((resolve: PromiseBase64) => {
        let reader = new FileReader();
        reader.onload = function (event: ProgressEvent<FileReader>) {
            let base64 = event.target!.result;
            // 压缩图片
            dealImage(base64 as string, 1000, (newBase64) => {
                resolve(newBase64);
            })
        };
        reader.readAsDataURL(file);
    })
}
/**
 * 图片压缩
 * @param base64 
 * @param w 目标宽度
 * @param callback 
 */
export function dealImage(base64: string, w: number, callback: (newBase64: string) => void) {
    const newImage = new Image();
    let quality = 0.6;    // 压缩系数0-1之间，图片质量
    newImage.src = base64;
    newImage.setAttribute("crossOrigin", 'Anonymous');	//url为外域时需要
    let imgWidth, imgHeight;
    newImage.onload = function () {
        imgWidth = newImage.width;
        imgHeight = newImage.height;
        const canvas = document.createElement("canvas");
        const ctx = canvas.getContext("2d")!;
        // 如果高度或者宽度大于目标宽度
        if (Math.max(imgWidth, imgHeight) > w) {
            if (imgWidth > imgHeight) {
                canvas.width = w;
                canvas.height = w * imgHeight / imgWidth;
            } else {
                canvas.height = w;
                canvas.width = w * imgWidth / imgHeight;
            }
        } else {
            canvas.width = imgWidth;
            canvas.height = imgHeight;
            quality = 0.6;
        }
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.drawImage(newImage, 0, 0, canvas.width, canvas.height);
        const base64 = canvas.toDataURL("image/jpeg", quality); //压缩语句
        // 如想确保图片压缩到自己想要的尺寸,如要求在50-150kb之间，请加以下语句，quality初始值根据情况自定
        // while (base64.length / 1024 > 150) {
        // 	quality -= 0.01;
        // 	base64 = canvas.toDataURL("image/jpeg", quality);
        // }
        // 防止最后一次压缩低于最低尺寸，只要quality递减合理，无需考虑
        // while (base64.length / 1024 < 50) {
        // 	quality += 0.001;
        // 	base64 = canvas.toDataURL("image/jpeg", quality);
        // }
        callback(base64);//必须通过回调函数返回，否则无法及时拿到该值
    }
}
/**
 * 按比例压缩
 * @param file 图片文件 
 * @param ratio 压缩比例
 * @param callback 获取回调
 */
export function scaleDealImage(file: File, ratio: number, callback: (newBase64: string) => void) {
    const render = new FileReader();
    render.onload = (event: ProgressEvent<FileReader>) => {
        const img = new Image();
        img.onload = () => {
            const canvas = document.createElement('canvas');
            const ctx = canvas.getContext("2d")!;
            const width = img.width * ratio;
            const height = img.height * ratio;

            canvas.width = width;
            canvas.height = height;

            ctx.drawImage(img, 0, 0, width, height);
            const base64 = canvas.toDataURL("image/jpeg", 0.7);
            callback(base64);
        };
        img.src = event.target!.result as string;
    };
    render.readAsDataURL(file);
}
/**
 * 文件下载
 * @param file 下载文件的file
 * @param fileName 文件名：默认原文件名
 */
export function fileDownload(file: File, fileName?: string) {
    const a = document.createElement('a');
    const url = window.URL.createObjectURL(file);
    a.href = url;
    // 指定下载的文件名
    a.download = fileName || file.name;
    a.click();
    window.URL.revokeObjectURL(url);
    a.remove();
}
/**
 * blob对象文件下载
 * @param blob  下载文件的blob
 * @param fileName 文件名：默认时间戳
 */
export function blobDownload(blob: Blob, fileName?: string) {
    const a = document.createElement('a');
    const url = window.URL.createObjectURL(blob);
    a.href = url;
    // 指定下载的文件名
    a.download = fileName || new Date().getTime().toString();
    a.click();
    window.URL.revokeObjectURL(url);
    a.remove();
}
/**
 * base64文件下载
 * @param base64 下载文件的base64
 * @param fileName 文件名，默认时间戳
 */
export function base64Download(base64: string, fileName?: string) {
    const a = document.createElement('a');
    const url = base64;
    a.href = url;
    // 指定下载的文件名
    a.download = fileName || new Date().getTime().toString();
    a.click();
    a.remove();
}
/**
 * 下载图片
 * @param imgsrc 下载图片的网络地址
 * @param fileName 文件名，默认时间戳 
 */
export function downloadIamge(imgsrc: string, fileName?: string) { // 下载图片地址和图片名
    var image = new Image();
    // 解决跨域 Canvas 污染问题
    image.setAttribute('crossOrigin', 'anonymous');
    image.onload = function() {
        const canvas = document.createElement('canvas');
        canvas.width = image.width;
        canvas.height = image.height;
        const context = canvas.getContext('2d');
        context!.drawImage(image, 0, 0, image.width, image.height);
        const url = canvas.toDataURL('image/png'); //得到图片的base64编码数据
        const a = document.createElement('a'); // 生成一个a元素
        a.download = fileName || new Date().getTime().toString(); // 设置图片名称
        a.href = url; // 将生成的URL设置为a.href属性
        a.click(); // 触发a的单击事件
        window.URL.revokeObjectURL(url);
		a.remove();
    }
    image.src = imgsrc;
}
/**
 * 下载文件 本身需要跨域
 * @param url 下载文件的地址
 * @param filename 下载文件名，默认file
 */
export function download(url: string, filename = 'file') {
    fetch(url, {
      headers: new Headers({
        Origin: location.origin,
      }),
      mode: 'cors'
    })
      .then(res => res.blob())
      .then(blob => {
        const blobUrl = window.URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.download = filename;
        a.href = blobUrl;
        a.click();
        a.remove();
        window.URL.revokeObjectURL(blobUrl);
      })
  }